import os
import sys
import threading
import time
from datetime import datetime, timedelta
import hashlib
import base64
import hmac

import requests
import json

# 获取项目文件路径
current_dir = os.path.dirname(__file__)
# 提取项目根路径
root_dir = os.path.abspath(os.path.join(current_dir, os.pardir))
# 将项目根路径存入，以便命令行运行时可以成功引包
sys.path.append(root_dir)

from FollowCourse.log import logger
from FollowCourse.Tool import get_token, get_new_token, write_today_live


class FollowCourseTool:
    def __init__(self):
        # 飞书机器人的Webhook URL
        # self.feishu_parameters = ["https://open.feishu.cn/open-apis/bot/v2/hook/ff36161e-6c03-4162-979d-d540078fc87d",
        #                           "fvK8eObSkyeSDKfDLmqIdh"]  # 测试用
        self.feishu_parameters = ["https://open.feishu.cn/open-apis/bot/v2/hook/87e75690-0aee-4263-ab22-4800e6b88e6a",
                                  "AoSTauAXdbSclMpHkuytTh"]
        self.course_follow_url = 'https://mobile.fengjinketang.com/client-h5/pages/courseFollower/index?roundList='
        self.roundId_roomId_dict = {}  # 初始化存放直播间id与到课人数的字典（存体验课类型）
        self.roundId_roomId_dict_only_start_live = {}  # 初始化值监听开播状态的直播间
        self.filter_keywords = ['测试', 'test', '废弃', '废', '学期', '磨课']  # 定义需要过滤的关键字
        # 定义筛选时间范围
        self.start_time_round = datetime.strptime("18:00", "%H:%M")
        self.end_time_round = datetime.strptime("20:00", "%H:%M")
        # 直播间域名，报警用
        self.live_url = 'https://mobile.fengjinketang.com/client-h5/live?roundId='
        # 获取token
        self.token = get_token()
        # 定义要筛选直播间消息的字典，大概这种格式：带“卡”“ka”“断断续续”“不动”关键词的，在其中过滤掉“不卡”“没有卡”“打卡”。
        # key：对这组消息的统称，报警时用到。
        # value：是一个列表，列表里字段分别代表：1：监控带这些关键词的；2、在其中过滤掉这些；
        self.sift_word = {
            '卡': [('卡', 'ka', '断断续续', '不动'), ('不卡', '没有卡', '打卡', '卡农', '斯卡', '卡卡老师', '链接')],
            '声音': [('声音', '听不见', '沒聲音', '没声'), (
                '有声音', '可以', '正好', '不小', '很大', '很好', '正常', '没问题', '不会小', '清晰', '好听', '优美',
                '动听', '气不断', '落下', '轻松', '愉快')],
            '黑屏': [('黑屏', '黑频', '没画面', '没老师', '没有老师'), ('没有黑', '不黑', '没有黑屏', '不黑屏', '好')]
        }
        self.start_time_message = '18:50:00'  # 定义监控消息的开始时间
        self.end_time_message = '21:00:00'  # 定义监控消息的结束时间
        self.bad_message_time = 120  # 定义监控消息的区间，单位秒（统计距当前时间xx秒之内的消息）

    def get_feishu_sign(self):
        """
        获取飞书请求密钥
        :return: 返回时间戳和签名
        """
        t = int(time.time())
        secret = self.feishu_parameters[1]

        # 拼接timestamp和secret
        string_to_sign = '{}\n{}'.format(t, secret)
        hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()

        # 对结果进行base64处理
        sign = base64.b64encode(hmac_code).decode('utf-8')

        return t, sign

    def get_round_datas(self, is_write=False, is_only_start_live=False):
        """
        获取未开播的直播数据
        :return: 返回一个字典，直播间id是key，[roomId，开播时间，直播类型拼成列表]是value
        """
        url = "https://crm.hongsong.info/gateway/api/fjkt-crm-course-ui-interfaces/v2/course/round-page"
        headers = {
            'loginsource': 'crm',
            'priority': 'u=1, i',
            'token': self.token,
            'userid': 'null',
            'x-hs-employee-token': '[object Object]',
            'content-type': 'application/json'
        }

        num = 1
        self.roundId_roomId_dict = dict()  # 将字典置空
        self.roundId_roomId_dict_only_start_live = dict()  # 将字典置空

        logger.log_info('执行获取未开播体验课数据的方法')
        while True:
            payload = json.dumps({
                "liveState": 0,
                "roundStateCode": 1,
                "roundTypes": [],
                "current": num,
                "pageSize": 20,
                "roundStartTime": f"{str(time.strftime('%Y-%m-%d'))} 00:00:00",
                "roundEndTime": f"{str(time.strftime('%Y-%m-%d'))} 23:59:59"
            })
            response = requests.request("POST", url, headers=headers, data=payload)

            for round_data in response.json()['data']['data']:
                # 课程名不包含filter_keywords里面定义的这些关键词,且开播时间在18:00--20:00之间且类型为体验课的
                if ((all(keyword not in round_data['roundName'].lower() for keyword in self.filter_keywords) and
                     self.start_time_round <= datetime.strptime(round_data['roundStartTime'].split()[1][0:5],
                                                                "%H:%M") <= self.end_time_round)):
                    logger.log_info(f'符合条件的场次：{json.dumps(round_data, ensure_ascii=False)}')
                    # # 将直播间id当做key，[roomId，开播时间，直播类型拼成列表]当做value存入字典
                    # self.roundId_roomId_dict_only_start_live[round_data['id']] = [round_data["roomId"], round_data["liveTypeCode"],
                    #                                                               round_data["roundStartTime"]]
                    if round_data['roundType'] == 1:  # 存体验课的数据，监控消息只监控体验课
                        self.roundId_roomId_dict[round_data['id']] = [round_data["roomId"], round_data["liveTypeCode"],
                                                                      round_data["roundStartTime"]]
                        # 正式课、加餐课
                    if round_data['roundType'] in (3, 4) and round_data['liveTypeCode'] in (13, 14):
                        self.roundId_roomId_dict_only_start_live[round_data['id']] = [round_data["roomId"],
                                                                                      round_data["liveTypeCode"],
                                                                                      round_data["roundStartTime"]]

            if num >= response.json()['data']['totalPage']:
                break
            else:
                num = num + 1

        # 把体验课的数据添加到仅监听开播状态的数据后面
        self.roundId_roomId_dict_only_start_live.update(self.roundId_roomId_dict)
        logger.log_info(
            f'监听消息和开播状态的直播间{len(self.roundId_roomId_dict)}个：{json.dumps(self.roundId_roomId_dict, ensure_ascii=False)}')
        logger.log_info(
            f'仅监开播状态的直播间{len(self.roundId_roomId_dict_only_start_live)}个：{json.dumps(self.roundId_roomId_dict_only_start_live, ensure_ascii=False)}')

        # 传参is_only_start_live表示仅监听开播状态，就只返回这些数据
        if is_only_start_live:
            return self.roundId_roomId_dict_only_start_live
        else:
            # 把今日直播数据写入到文件中
            if is_write:
                write_today_live(self.roundId_roomId_dict)
            return self.roundId_roomId_dict

    # 定义消息内容并发送飞书消息
    def send_feishu_round(self):
        """
        将体验课信息组装好并发送到飞书群
        :return: 无返回值
        """
        all_roundId = []  # 初始化全部直播间id列表
        split_roundId = []  # 初始化拆分直播间id列表
        roundid_roomid_dict = self.get_round_datas(is_write=True, is_only_start_live=False)  # 获取直播数据
        # 将直播间id单独取出来，存入列表
        for i, y in roundid_roomid_dict.items():
            all_roundId.append(i)
        # 将直播间id分成两份
        length = len(all_roundId)
        middle = length // 2
        if length % 2 == 0:
            split_roundId = all_roundId[:middle], all_roundId[middle:]
        else:
            split_roundId = all_roundId[:middle + 1], all_roundId[middle + 1:]
        # 拼接网址
        course_follow_url_all = self.course_follow_url + '_'.join(map(str, all_roundId))
        course_follow_url_front = self.course_follow_url + '_'.join(map(str, split_roundId[0]))
        course_follow_url_after = self.course_follow_url + '_'.join(map(str, split_roundId[1]))
        logger.log_info(f'数量：{len(all_roundId)}')
        logger.log_info(f'体验课全部直播间的地址：{course_follow_url_all}')
        logger.log_info(f'体验课前一半直播间的地址：{course_follow_url_front}')
        logger.log_info(f'体验课后一半直播间的地址：{course_follow_url_after}')

        timestamp, sign = self.get_feishu_sign()

        # 定义要发送的消息内容
        data = {
            "timestamp": timestamp,
            "sign": sign,
            "msg_type": "interactive",
            "card": {
                "config": {
                    "wide_screen_mode": True
                },
                "header": {
                    "title": {
                        "content": f"{str(time.strftime('%Y-%m-%d'))}",
                        "tag": "plain_text"
                    }
                },
                "elements": [
                    {
                        "tag": "div",
                        "text": {
                            "content": f"筛选条件：开播时间在当天18:00--20:00之间，状态是上架的且未开播的体验课节，过滤掉直播间名字带这些关键词的：{self.filter_keywords}，共{len(all_roundId)}个体验课节",
                            "tag": "lark_md"
                        }
                    },
                    {
                        "tag": "action",
                        "actions": [
                            {
                                "tag": "button",
                                "text": {
                                    "content": f"点我打开前面{len(split_roundId[0])}个直播间",
                                    "tag": "lark_md"
                                },
                                "url": f"{course_follow_url_front}"
                            },
                            {
                                "tag": "button",
                                "text": {
                                    "content": f"点我打开后面{len(split_roundId[1])}个直播间",
                                    "tag": "lark_md"
                                },
                                "url": f"{course_follow_url_after}"
                            },
                            {
                                "tag": "button",
                                "text": {
                                    "content": "点我打开全部直播间",
                                    "tag": "lark_md"
                                },
                                "url": f"{course_follow_url_all}"
                            }
                        ]
                    }
                ]
            }
        }

        # 发送POST请求
        response = requests.post(self.feishu_parameters[0], json=data, headers={"Content-Type": "application/json"})
        logger.log_info(response.text)

    def monitor_message(self, roundid_roomid_dict=None):
        """
        将需要监听直播间分组，然后多线程调用监听消息的方法
        :param roundid_roomid_dict: 如果不传参，就监听上面取到的直播间，如果传参，就监听传参的直播间+上面取到的直播间
        :return: 无返回值
        """
        # 如果不传参，就监听上面取到的直播间，如果传参，就监听传参的直播间+上面取到的直播间
        if roundid_roomid_dict is None:
            roundid_roomid_dict = self.roundId_roomId_dict
        else:
            roundid_roomid_dict.update(self.roundId_roomId_dict)

        # 往需要监控的直播间的字典中添加默认数据（消息列表，监控消息的命中数、2分钟内消息总数等）
        for i, y in roundid_roomid_dict.items():
            y.append([])
            y.append({key: 0 for key in self.sift_word.keys()})
            y.append(0)

        logger.log_info(
            f'监控消息的直播间{len(roundid_roomid_dict)}个：{json.dumps(roundid_roomid_dict, ensure_ascii=False)}')

        num_splits = 2  # 定义想要分组的数量
        split_dicts = []  # 初始化存放分组后数据的空列表
        # 将下面数据分成指定组
        keys = list(roundid_roomid_dict.keys())
        chunk_size = len(keys) // num_splits
        remainder = len(keys) % num_splits

        start = 0
        for i in range(num_splits):
            if remainder > 0:
                end = start + chunk_size + 1
                remainder -= 1
            else:
                end = start + chunk_size
            new_dict = {key: roundid_roomid_dict[key] for key in keys[start:end]}
            split_dicts.append(new_dict)
            start = end

        logger.log_info(f'监控消息的直播间分成{len(split_dicts)}组后：{json.dumps(split_dicts, ensure_ascii=False)}')

        # 遍历分组后的数据，每一组数据单独起一个线程执行
        for i in split_dicts:
            thread = threading.Thread(target=self.monitor_message2, args=(i,))
            thread.start()

    def monitor_message2(self, roundid_roomid_dict2=None):
        """
        实际监听消息的操作
        :param roundid_roomid_dict2: 直播间
        :return: 无返回值
        """
        url = "https://crm.hongsong.info/crmapi/api/edu-fengjin-admin-web/chart/chatMessages"
        # last_notification_time_dict = {}  # 初始化报警消息上一次发送的时间，用来限制同一个直播间短时间内不重复发消息
        ordered_keys = list(roundid_roomid_dict2.keys())  # 将字典的key取出来，存入列表，当一个有序建，业务上没有用，日志用

        while True:
            if time.strftime('%H:%M:%S') >= self.end_time_message:
                logger.log_info(f'超过{self.end_time_message}了，停止监听直播消息！！！！！！')
                return
            if time.strftime('%H:%M:%S') >= self.start_time_message:
                for roundid, round_detail in roundid_roomid_dict2.items():
                    # 求当前时间小60s（配置）的时间
                    current_time = datetime.now()
                    one_minute_ago = current_time - timedelta(seconds=self.bad_message_time)
                    formatted_time = one_minute_ago.strftime('%Y-%m-%d %H:%M:%S')

                    current = 1  # 页码
                    round_detail[3] = []  # 初始化消息列表

                    # "{:02d}".format() 表示将整数格式化为至少两位数字，如果不足两位则在前面补零
                    logger.log_info(
                        f'直播间消息持续监测中({"{:02d}".format(ordered_keys.index(roundid) + 1)}:{"{:02d}".format(len(ordered_keys))})======{roundid}=={round_detail[0]}')

                    while True:
                        headers = {
                            'loginsource': 'crm',
                            'priority': 'u=1, i',
                            'token': self.token,
                            'userid': 'null',
                            'x-hs-employee-token': '[object Object]',
                            'content-type': 'application/json'
                        }
                        payload = json.dumps({
                            "data": {
                                "current": current,
                                "pageSize": 100,
                                "roundId": roundid,
                                "roomId": round_detail[0],
                                "desc": True
                            }
                        })

                        try:
                            response = requests.request("POST", url, headers=headers, data=payload)
                            current += 1
                            time.sleep(0.5)
                            if current > 2:
                                logger.log_info(f'当前直播间{roundid}两分钟内评论数超过一页，分页进行请求{current}')
                            # 如果token失效，则获取新token    {"state":{"code":"401","msg":"未登录"},"success":false,"timestamp":0}
                            if response.json()['state']['code'] == '401' and response.json()['state'][
                                'msg'] == "未登录":
                                self.token = get_new_token()
                        except Exception as ee:
                            # 处理其他未特定处理的异常的代码
                            logger.log_info(f"发生了未知错误：{ee}")
                            time.sleep(10)

                        try:
                            # 取出响应里面的消息列表
                            round_detail[3].extend(response.json()['data']['data'])

                            if len(response.json()['data']['data']) > 0:
                                if formatted_time < response.json()['data']['data'][-1]['sendTime']:
                                    pass
                                    # print('本次请求的最后一条的消息的发送时间不在两分钟前')
                                else:
                                    # print('本次请求的最后一条的消息的发送时间在两分钟前，停止循环')
                                    break
                            else:
                                logger.log_info(f'直播间没有消息：{roundid}')
                                break
                        except:
                            # 异常，给消息列表赋空列表，以免程序中断
                            round_detail[3].extend([])

                            logger.log_info('没取出数据，给个默认空值！！！')

                    # 将本次轮训的直播间的监控消息组中的计数器归0
                    for key in round_detail[4]:
                        round_detail[4][key] = 0
                    round_detail[5] = 0  # 初始化两分钟内的消息数量!!!!!!

                    # 轮训消息列表
                    for i in round_detail[3]:
                        # 求当前时间小120s（配置）的时间
                        current_time = datetime.now()
                        one_minute_ago = current_time - timedelta(seconds=self.bad_message_time)
                        formatted_time = one_minute_ago.strftime('%Y-%m-%d %H:%M:%S')

                        # 判断消息的发送时间距离当前120秒（配置）内
                        if i['sendTime'] >= formatted_time:
                            round_detail[5] += 1  # 消息数+1!!!!
                            # 获取到的直播间消息，与定义好的监控消息组进行判断
                            for key, value in self.sift_word.items():
                                if any(keyword in i['chatMsg'].lower() for keyword in value[0]) and all(
                                        keyword not in i['chatMsg'].lower() for keyword in value[1]):
                                    round_detail[4][key] = round_detail[4][key] + 1

                    for key, value in round_detail[4].items():
                        # # 判断监听的消息出现5次，且这个直播间10秒钟内没有发送报警消息
                        # if value >= 5 and time.time() - last_notification_time_dict.get(roundid, 0) > 10:
                        # 判断监听的消息出现5次
                        if value >= 5:
                            live_online_people = self.get_live_online_people(round_detail[0])  # 调用获取当前在线人数的方法

                            logger.log_info(
                                f'直播间{roundid}--{round_detail[0]}当前在线人数{live_online_people},在过去的{self.bad_message_time}秒内，共产生了{round_detail[5]}条消息，其中有{value}条【{key}】相关的消息，请进入直播间查看：{self.live_url + str(roundid)}')
                            # 将消息发送到飞书
                            self.send_alarm_message_to_feishu(roundid, value, key, 1,
                                                              time_range_message_num=round_detail[5],
                                                              live_online_people=live_online_people,
                                                              roomid=round_detail[0])
                            # last_notification_time_dict[roundid] = time.time()  # 发送成功，将当前时间记为这个直播间上一次发送的时间！！！！！！！！

                    time.sleep(1)
            else:
                logger.log_info(f'设定的直播间消息监听范围： {self.start_time_message}--{self.end_time_message}，'
                                f'还没到设定的开始监听监听时间呢！！！')
                time.sleep(60)

    def send_alarm_message_to_feishu(self, roundid, num=None, keyword=None, send_type=None, live_typ=None,
                                     live_online_people=None, time_range_message_num=None, roomid=None):
        """
        将报警消息发送到飞书：格式如下：直播间xxx在过去的xx秒内，产生了xx条【xx】相关的消息
        :param roomid: 直播间roomid
        :param time_range_message_num: 分钟内产品的消息总数
        :param live_online_people: 直播间当前在线人数
        :param live_typ: 直播类型（直播，录播）
        :param send_type: 消息发送类型（1、消息报警，2、直播状态报警）
        :param roundid: 直播间id
        :param num: 数量，报警时用来统计
        :param keyword: 消息组的统称
        :return: 无返回值
        """
        # 获取时间戳和秘钥
        timestamp, sign = self.get_feishu_sign()
        # 定义要发送的消息内容
        if send_type == 1:
            data1 = {
                "timestamp": timestamp,
                "sign": sign,
                "msg_type": "text",
                "content": {
                    "text": f"直播间{roundid}--{roomid}当前在线人数{live_online_people}，在过去的{self.bad_message_time}秒内，共产生了{time_range_message_num}条消息，其中有{num}条【{keyword}】相关的消息，请进入直播间查看：{self.live_url + str(roundid)}"
                }
            }
            response1 = requests.post(self.feishu_parameters[0], json=data1,
                                      headers={"Content-Type": "application/json"})
            logger.log_info(f'调用飞书发送异常消息的报警:{response1.text}')
        elif send_type == 2:
            data1 = {
                "timestamp": timestamp,
                "sign": sign,
                "msg_type": "text",
                "content": {
                    "text": f"【{live_typ}】{roundid}--{roomid}还没开播，请进入直播间查看：{self.live_url + str(roundid)}"
                }
            }
            response1 = requests.post(self.feishu_parameters[0], json=data1,
                                      headers={"Content-Type": "application/json"})
            logger.log_info(f'调用飞书发送未开播的报警:{response1.text}')

    def monitor_live_state(self):
        """
        获取到需要监听开播状态的直播间，将其按照时间分组，启用多线程每组数据单独监听
        :return: 无返回值
        """
        # # 监听上面取到的直播间
        # roundid_roomid_dict = self.roundId_roomId_dict
        # 监听上面取到的所有直播间
        roundid_roomid_dict = self.roundId_roomId_dict_only_start_live
        logger.log_info(
            f'监控直播状态的直播间{len(roundid_roomid_dict)}个：{json.dumps(roundid_roomid_dict, ensure_ascii=False)}')
        # 创建一个空字典用于存储分组后的数据
        grouped_datas = {}

        # 遍历数据，按照时间将数据分组
        for key, value in roundid_roomid_dict.items():
            time_str = value[2]
            if time_str in grouped_datas:
                grouped_datas[time_str].append((key, value))
            else:
                grouped_datas[time_str] = [(key, value)]

        logger.log_info(
            f'监控开播状态的直播间按照开播时间分成{len(grouped_datas)}组后的数据：{json.dumps(grouped_datas, ensure_ascii=False)}')

        # 遍历分组后的数据
        for grouped_data in grouped_datas.items():
            # 每一组数据单独起一个线程执行
            thread = threading.Thread(target=self.monitor_live_state2, args=(grouped_data,))
            thread.start()
            # print(f'当前线程数量：{threading.active_count()}')

    def monitor_live_state2(self, grouped_data):
        """
        对按照开播时间分组后一组数据进行开播监听的操作
        :param grouped_data: 按照开播时间分组后一组数据
        :return:
        """
        # 取出里面的时间组，将字符串转换为datetime对象
        given_time_str = grouped_data[0]
        given_time = datetime.strptime(given_time_str, "%Y-%m-%d %H:%M:%S")
        # 计算距离时间组前xx秒和后xx秒的时间，判断什么时候开始执行监控直播状态用
        xx_seconds_before = given_time - timedelta(seconds=0)
        xx_seconds_after = given_time + timedelta(seconds=180)
        logger.log_info(f'【{given_time_str}】组里面的数据:{json.dumps(grouped_data, ensure_ascii=False)}')
        logger.log_info(f'【{given_time_str}】组里面开始监听的时间:{xx_seconds_before}，停止监听的时间{xx_seconds_after}')

        # 遍历传递过来的数据，取出等待监控的直播间id当做key，设定一个报警次数（默认0）当做value
        wait_monitor_round = {i[0]: 0 for i in grouped_data[1]}

        while True:
            # 判断当前时间在上面设定的开始执行监控时间的范围之内
            if xx_seconds_after >= datetime.now() >= xx_seconds_before:
                # 调用获取未开播直播间的方法，将数据换成列表，方便后续判断
                not_live_round_datas = self.get_round_datas(is_only_start_live=True)
                logger.log_info(f'接口查出来的未开播的直播间--字典形式:{not_live_round_datas}')
                not_live_round_list = [i[0] for i in not_live_round_datas.items()]
                logger.log_info(f'接口查出来的未开播的直播间--列表形式:{not_live_round_list}')
                logger.log_info(f'【{given_time_str}】组里面的数据:{json.dumps(grouped_data, ensure_ascii=False)}')

                # 如果需要监听的直播间全部都开播了，就结束程序
                if all(round_id not in not_live_round_list for round_id, y in wait_monitor_round.items()):
                    logger.log_info(f'【{given_time_str}】组里面的直播已经全部开播，停止监听这个组')
                    return
                # 遍历需要监控的直播间id，判断其是不是在未开播的直播间里面
                for round_id, send_times in wait_monitor_round.items():
                    if round_id in not_live_round_list:
                        logger.log_info(
                            f'{round_id}--{not_live_round_datas[round_id][1]}没有开播({send_times + 1})！！！！！！！！！！！！！!!')
                        # 同一个直播间，一直未开播，最多报警5次
                        if send_times < 5:
                            # 10横屏直播 11竖屏直播 13录播竖屏直播 14录播横屏直播
                            # 类型是录播时，监控到到点未开播直接发通知
                            if not_live_round_datas[round_id][1] in [13, 14]:
                                self.send_alarm_message_to_feishu(roundid=round_id, send_type=2, live_typ='录播',
                                                                  roomid=not_live_round_datas[round_id][0])
                                wait_monitor_round[round_id] += 1  # 消息发送完毕，发送次数+1

                            # 类型是直播时，需要判断当前时间比开播时间晚30秒，才发通知
                            elif not_live_round_datas[round_id][1] in [10, 11]:
                                # 获取时间组的开播时间的时间戳（以秒为单位）
                                given_timestamp = datetime.strptime(given_time_str, "%Y-%m-%d %H:%M:%S").timestamp()
                                # 获取当前时间的时间戳（以秒为单位），判断当前时间戳是否比给定时间戳晚 30 秒以上才发通知
                                now_timestamp = datetime.now().timestamp()

                                if now_timestamp - given_timestamp > 30:
                                    self.send_alarm_message_to_feishu(roundid=round_id, send_type=2, live_typ='直播',
                                                                      roomid=not_live_round_datas[round_id][0])
                                    wait_monitor_round[round_id] += 1  # 消息发送完毕，发送次数+1
                time.sleep(10)
            elif xx_seconds_after < datetime.now():
                logger.log_info(f'时间组【{grouped_data[0]}】已过监控时间，停止监听开播状态')
                return
            else:
                logger.log_info(
                    f'当前组的开播时间为【{grouped_data[0]}】，监听时间{xx_seconds_before}--{xx_seconds_after}，'
                    f'还未到开始监听直播状态的时间')
                time.sleep(60)

    def get_live_online_people(self, roomid):
        url = "https://crm.hongsong.info/gateway/api/fjkt-crm-course-ui-interfaces/v1/live/list/liveEffectData"
        payload = json.dumps({
            "roomId": roomid
        })
        headers = {
            'loginsource': 'crm',
            'pragma': 'no-cache',
            'priority': 'u=1, i',
            'token': self.token,
            'userid': 'null',
            'x-hs-employee-token': '[object Object]',
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'content-type': 'application/json'
        }

        try:
            response = requests.request("POST", url, headers=headers, data=payload)

            people_num = 0
            if response.json()['data']['liveEffectDataVOList'] is not None:
                people_num = response.json()['data']['liveEffectDataVOList'][-1]['nowPersons']

            return people_num
        except Exception as eee:
            # 处理其他未特定处理的异常的代码
            logger.log_info(f"发生了未知错误：{eee}")
            people_num = 0
            return people_num


if __name__ == '__main__':
    try:
        # 判断当前时间是整分或刚过整分才往下执行
        while True:
            logger.log_info('等待中===')
            if datetime.now().second <= 3:
                break
            time.sleep(1)

        # 实例化跟课工具类
        fct = FollowCourseTool()
        # 调用发送跟课信息的方法
        fct.send_feishu_round()

        # 定义两个线程，一个执行监控消息的操作，一个执行监控直播状态的操作
        thread_message = threading.Thread(target=fct.monitor_message, args=())
        thread_live_state = threading.Thread(target=fct.monitor_live_state, args=())

        # 启动线程
        thread_message.start()
        thread_live_state.start()

        # 等待线程执行完毕
        thread_message.join()
        thread_live_state.join()

    except Exception as e:
        print("发生了异常,程序停止:", e)
        logger.log_info(f'发生了异常,程序停止:{e}')
